﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace BioCyber_Infection.Class.Screens.Stagees
{
    class Stagee1 : Stagee
    {
        #region Begin of Declaration
        public Enemy[] enemyies = new Enemy[2];
        private ContentManager content;
        private GameWindow window;
        #endregion


        #region Constructor
        public Stagee1(ContentManager content, GameWindow gameWindow)
        {
            this.content = content;
            this.window = gameWindow;
            enemyies[0] = new Enemy(content, gameWindow, content.Load<Texture2D>("player2"));
        }
        #endregion

        #region Draw Method
        public override void Draw(SpriteBatch spriteBatch, GameTime gametime)
        {
            foreach (NetworkGamer gamer in Network.networkSession.AllGamers)
            {
                Player player = gamer.Tag as Player;
                player.Draw(gamer,spriteBatch, content, gametime);

                enemyies[0].Draw(gametime, spriteBatch, enemyies[0].Stopped);
            }
        }
#endregion

        #region LoadContent Method
        public override void LoadContent(ContentManager content)
        {
            throw new NotImplementedException();
        }
        #endregion

        /// <About Update Method...>
        /// Todo stage deve ter em seu método UPDATE algumas características
        /// fundamentais como: importar dados e exportar dados para a rede, 
        /// como acontece no método a seguir
        /// </summary>
        /// <param name="gameTime"></param>
        #region Update Method
        public override void Update(GameTime gameTime)
        {
            if (!Guide.IsVisible)
            {
                foreach (LocalNetworkGamer signedInGamer in Network.networkSession.LocalGamers)
                {
                    Player player = signedInGamer.Tag as Player;

                    UpdatePlayersInput(player, gameTime);
                    //Atualiza a posição de cada jogador, e então passa-os pela rede

                    player.Update(signedInGamer.SignedInGamer.PlayerIndex);
                    //Atualiza as características do jogador (posição,rotação)
                }

                if (Network.networkSession.IsHost /*&& gameTime.TotalGameTime.Seconds%2==0*/)
                {
                    enemyies[0].posicao.X -= 1;
                    //Inteligência artificial do inimigo (muito escrota, mas se está funcional, podemos fazer muito mais.

                    LocalNetworkGamer localGamer = Network.networkSession.Host as LocalNetworkGamer;
                    //Definição do gamer local preparando para o envio de dados.

                    Engine.packetWriter.Write(1);
                    //Envio do TIPO do Package que deve ser lido em Receivepackages

                    //--> Envio de informação
                    Engine.packetWriter.Write(enemyies[0].posicao);
                    //<--
                    
                    localGamer.SendData(Engine.packetWriter, SendDataOptions.ReliableInOrder);
                }
            }
        }
        #endregion

        /// <Sending player data...>
        /// Método que manda os dados de cada jogador para a rede,
        /// pois assim cada um colherá a informação que o outro enviou
        /// </summary>
        /// <param name="player"></param>
        /// <param name="gameTime"></param>
        #region Sending player DATA
        private void UpdatePlayersInput(Player player, GameTime gameTime)
        {
            foreach (LocalNetworkGamer gamer in Network.networkSession.LocalGamers)
            {
                ReceiveNetworkData(gameTime);
                //Recebimento dos dados

                //-->Envio de informações
                Engine.packetWriter.Write(0);
                Engine.packetWriter.Write(player.position);
                Engine.packetWriter.Write(player.rotation);
                //<--
                gamer.SendData(Engine.packetWriter, SendDataOptions.ReliableInOrder);
            }
        }
        #endregion

        /// <Principal Method about Receiving DATA>
        /// Método principal da classe.
        /// Tal método atualiza os dados que vem da rede e os atribui conforme
        /// o tipo de Package
        /// </summary>
        /// <param name="gameTime"></param>
        #region Receiving all DATA
        void ReceiveNetworkData(GameTime gameTime)
        {
            while (Network.networkSession.LocalGamers[0].IsDataAvailable)
            {//Enquanto houver informação provindoura do HOST, o While será verdadeiro

                NetworkGamer sender;
                Network.networkSession.LocalGamers[0].ReceiveData(Engine.packetReader, out sender);
                //Recebimento dos Dados em função do Host

                switch (Engine.packetReader.ReadInt32())//Verifica qual o tipo de dado que deve ser lido
                {
                    case (0)://Caso o tipo de dado a ser lido seja o dos jogadores...
                        if (!sender.IsLocal)
                        {
                            Player player = sender.Tag as Player;
                            //-->Recebimento de dados
                            player.position = Engine.packetReader.ReadVector2();
                            player.rotation = Engine.packetReader.ReadSingle();
                            //<--
                        }
                        break;
                    case (1)://Caso o tipo de dado a ser lido seja o dos Inimigos...
                        enemyies[0].posicao = Engine.packetReader.ReadVector2();
                        break;
                }
            }
        }
        #endregion


        
    }
}